/* entity */
import MsgModel from '@model/MsgModel'
import Result from '@model/Result'
/* util */
import { isFunction } from '@src/util/type'
import Platform from '@src/util/platform'
/* vue */
import { computed, ComputedRef, Ref, ref } from 'vue'

function useFetch<Params, ResultType>(
  fetchFunction: (params: Params) => Promise<Result<ResultType>>, 
  params: Params
): [Ref<Result<ResultType | null>>, Function, Ref<boolean>, ComputedRef<boolean>, ComputedRef<string>] {
  
  // 返回结果
  let result: Ref<Result<ResultType | null>> = ref(new Result(Result.FAIL, '', false, null))
  // 加载状态
  let loading: Ref<boolean> = ref(false)
  const isSuccess: ComputedRef<boolean> = computed(() => result.value.success)
  const message: ComputedRef<string> = computed(() => result.value.message)
  
  const callbackFunction = () => {
    
    loading.value = true
    
    return (
      fetchFunction(params)
        .then((responseData: Result<ResultType> | MsgModel<ResultType>) => {
          // @ts-ignore
          const isSuccess = Boolean(responseData?.success || responseData?.succ || responseData?.status == 200)
          
          result.value.message = responseData?.message || ''
          
          if (!isSuccess) {
            result.value.code = Result.FAIL
            result.value.success = false
            Platform.alert(result.value.message)
          } else {
            result.value.code = Result.SUCCESS
            result.value.success = true
            // @ts-ignore
            result.value.result = (responseData?.result || responseData?.data)
          }
          
        })
        .catch(error => {
          result.value.code = Result.FAIL
          result.value.success = false
          result.value.result = null
          result.value.message = '系统错误'
        })
        .finally(() => {
          loading.value = false
        })
    )
    
  }
  
  return [result, callbackFunction, loading, isSuccess, message];
}

function useFetchResult<Params, ResultType>(
  fetchFunction: (params: Params) => Promise<Result<ResultType>>, 
  params: Params
): [Ref<ResultType | null>, Function] {
  
  let result: Ref<ResultType | null> = ref(null)
  
  const callbackFunction = (callback: Function) => {
    return (
      fetchFunction(params)
        .then((responseData: Result<ResultType> | MsgModel<ResultType>) => {
          // @ts-ignore
          const isSuccess = Boolean(responseData?.success || responseData?.succ || responseData?.status == 200)
          
          if (!isSuccess) {
            result.value = null
          } else {
            // @ts-ignore
            result.value = (responseData?.result || responseData?.data)
          }
          
          isFunction(callback) && callback(responseData)
        })
        .catch(error => {
          result.value = null
        })
    )
  }
  
  return [result, callbackFunction];
}

export {
  useFetchResult
}

export default useFetch
